using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Text.RegularExpressions;
using System.Data;
using System.Reflection;
using System.Xml;
using System.Diagnostics;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using Util;
using System.Messaging;

namespace SpiderService
{
	public class AnalyseThread : ThreadBase
	{
		private int parseThreadCount = 0;

		private AutoResetEvent signal;
		public AnalyseThread()
		{
			signal = new AutoResetEvent(true);
		}

		public void Set()
		{
			signal.Set();
		}

		protected override void DoWork()
		{
			while (this.started)
			{
				try
				{
					if (this.parseThreadCount < Globals.ParseThreadCount)
					{
						MessageQueue queue = Globals.DataItemMQ.MessageQueue;
						queue.ReceiveCompleted += new ReceiveCompletedEventHandler(QueueReceiveCompleted);
						queue.BeginReceive();

						signal.WaitOne();
					}
					Thread.Sleep(Globals.AnalyseThreadSleepTime);
				}
				catch (Exception ex)
				{
					Globals.FileLog.WriteError(ex);
				}
			}
		}

		private void QueueReceiveCompleted(Object objSource, ReceiveCompletedEventArgs aSyncResult)
		{
			try
			{
				MessageQueue mq = (MessageQueue)objSource;
				using (mq)
				{
					Message msg = mq.EndReceive(aSyncResult.AsyncResult);
					msg.Formatter = new BinaryMessageFormatter();

					WebDataInfo data = (WebDataInfo)msg.Body;
					IDataParser parser = CreateDataParser();
					parser.Complete += new EventHandler(parser_Complete);
					parser.Data = data;
					Thread t = new Thread(new ThreadStart(parser.Parse));
					t.IsBackground = true;
					t.Start();
					msg.Dispose();

					Interlocked.Increment(ref this.parseThreadCount);
				}
			}
			catch (Exception ex)
			{
				Globals.FileLog.WriteError(ex);
			}
			finally
			{
				Set();
			}
		}

		void parser_Complete(object sender, EventArgs e)
		{
			Interlocked.Decrement(ref parseThreadCount);
		}

		protected override void OnStop()
		{
			Set();
		}

		public static IDataParser CreateDataParser()
		{
			if (Globals.DataParserTypeName == null)
				return new DefaultDataParser();
			else
			{
				Type t = Types.GetType(Globals.DataParserTypeName);

				return Activator.CreateInstance(t) as IDataParser;
			}
		}

		public class MyBinder : SerializationBinder
		{
			public override Type BindToType(string assemblyName, string typeName)
			{
				return Type.GetType(typeName);
			}
		}
	}
}
